﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.UI;

namespace DNA.Mvc.jQuery
{
    public class RichTextBoxPaneBuilder : ViewComponentBuilder<RichTextBoxToolPane, RichTextBoxPaneBuilder>
    {
        public RichTextBoxPaneBuilder(RichTextBoxToolPane component, ViewContext context, IViewDataContainer container) : base(component, context, container) { }

        public RichTextBoxPaneBuilder CustomTools(Action<RichTextBoxToolbarFactory> tools)
        {
            var factory = new RichTextBoxToolbarFactory(this.Component, this.ViewContext,this.ViewDataContainer);
            tools.Invoke(factory);
            return this;
        }

        public RichTextBoxPaneBuilder AddFontTools()
        {
            var factory = new RichTextBoxToolbarFactory(this.Component, this.ViewContext,this.ViewDataContainer);

            var toolbar = factory.Add();

            toolbar.AddCombo(combo =>
            {
                #region Add font format combo

                combo.Items(items =>
                {
                    using (var writer = new HtmlTextWriter(this.ViewContext.Writer))
                    {
                        items.AddValue("format").Template(() =>
                        {
                            writer.Write("<span style=\"font-family: inherit;\">Format</span>");
                        });
                        items.AddValue("p").Template(() =>
                        {
                            writer.WriteBeginTag("p");
                            writer.WriteAttribute("style", "margin:0px");
                            writer.Write(HtmlTextWriter.TagRightChar);
                            writer.WriteFullBeginTag("span");
                            writer.Write("Paragraph");
                            writer.WriteEndTag("span");
                            writer.WriteEndTag("p");
                        });
                        items.AddValue("blockquote").Template(() =>
                        {
                            writer.WriteBeginTag("blockquote");
                            writer.WriteAttribute("style", "margin:0px");
                            writer.Write(HtmlTextWriter.TagRightChar);
                            writer.Write("Quotation");
                            writer.WriteEndTag("blockquote");
                        });
                        items.AddValue("h1").Template(() =>
                        {
                            writer.WriteBeginTag("h1");
                            writer.WriteAttribute("style", "margin:0px");
                            writer.Write(HtmlTextWriter.TagRightChar);
                            writer.Write("Heading 1");
                            writer.WriteEndTag("h1");
                        });

                        items.AddValue("h2").Template(() =>
                        {
                            writer.WriteBeginTag("h2");
                            writer.WriteAttribute("style", "margin:0px");
                            writer.Write(HtmlTextWriter.TagRightChar);
                            writer.Write("Heading 2");
                            writer.WriteEndTag("h2");
                        });
                        items.AddValue("h3").Template(() =>
                        {
                            writer.WriteBeginTag("h3");
                            writer.WriteAttribute("style", "margin:0px");
                            writer.Write(HtmlTextWriter.TagRightChar);
                            writer.Write("Heading 3");
                            writer.WriteEndTag("h3");
                        });
                        items.AddValue("h4").Template(() =>
                        {
                            writer.WriteBeginTag("h4");
                            writer.WriteAttribute("style", "margin:0px");
                            writer.Write(HtmlTextWriter.TagRightChar);
                            writer.Write("Heading 4");
                            writer.WriteEndTag("h4");
                        });
                        items.AddValue("h5").Template(() =>
                        {
                            writer.WriteBeginTag("h5");
                            writer.WriteAttribute("style", "margin:0px");
                            writer.Write(HtmlTextWriter.TagRightChar);
                            writer.Write("Heading 5");
                            writer.WriteEndTag("h5");
                        });
                        items.AddValue("h6").Template(() =>
                        {
                            writer.WriteBeginTag("h6");
                            writer.WriteAttribute("style", "margin:0px");
                            writer.Write(HtmlTextWriter.TagRightChar);
                            writer.Write("Heading 6");
                            writer.WriteEndTag("h6");
                        });
                    }
                })
                .Options(opts => { opts.OnItemSelected = "$(\"#" + Component.Parent.Id + "\").richtextbox(\"formatBlock\",$(this).val())"; })
                .Select("format");
                #endregion
            }, (id => { Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").combo(\"option\", \"selectedValue\", sender.getTagName().toLocaleLowerCase());"); }))
                //.Width(100)
            .AddCombo(combo =>
            {
                #region Add font name combo

                combo.Items(items =>
                    {
                        using (var writer = new HtmlTextWriter(this.ViewContext.Writer))
                        {
                            items.AddValue("inherit").Template(() =>
                            {
                                writer.WriteBeginTag("span");
                                writer.WriteAttribute("style", "font-family: inherit;");
                                writer.Write(HtmlTextWriter.TagRightChar);
                                writer.Write("(inherited font)");
                                writer.WriteEndTag("span");
                            });

                            items.AddValue("Arial").Template(() =>
                            {
                                writer.WriteBeginTag("span");
                                writer.WriteAttribute("style", "font-family: Arial,Helvetica,sans-serif;");
                                writer.Write(HtmlTextWriter.TagRightChar);
                                writer.Write("Arial");
                                writer.WriteEndTag("span");
                            });

                            items.AddValue("Courier New,Courier,monospace").Template(() =>
                            {
                                writer.WriteBeginTag("span");
                                writer.WriteAttribute("style", "font-family: 'Courier New',Courier,monospace;");
                                writer.Write(HtmlTextWriter.TagRightChar);
                                writer.Write("Courier New");
                                writer.WriteEndTag("span");
                            });

                            items.AddValue("Georgia,serif").Template(() =>
                            {
                                writer.WriteBeginTag("span");
                                writer.WriteAttribute("style", "font-family: Georgia,serif;");
                                writer.Write(HtmlTextWriter.TagRightChar);
                                writer.Write("Georgia");
                                writer.WriteEndTag("span");
                            });

                            items.AddValue("font-family: Impact,Charcoal,sans-serif").Template(() =>
                            {
                                writer.WriteBeginTag("span");
                                writer.WriteAttribute("style", "font-family: Impact,Charcoal,sans-serif;");
                                writer.Write(HtmlTextWriter.TagRightChar);
                                writer.Write("Impact");
                                writer.WriteEndTag("span");
                            });

                            items.AddValue("Lucida Console,Monaco,monospace").Template(() =>
                           {
                               writer.WriteBeginTag("span");
                               writer.WriteAttribute("style", "font-family: 'Lucida Console',Monaco,monospace;");
                               writer.Write(HtmlTextWriter.TagRightChar);
                               writer.Write("Lucida");
                               writer.WriteEndTag("span");
                           });

                            items.AddValue("Tahoma,Geneva,sans-serif").Template(() =>
                            {
                                writer.WriteBeginTag("span");
                                writer.WriteAttribute("style", "font-family: Tahoma,Geneva,sans-serif;");
                                writer.Write(HtmlTextWriter.TagRightChar);
                                writer.Write("Tahoma");
                                writer.WriteEndTag("span");
                            });

                            items.AddValue("Times New Roman,Times,serif").Template(() =>
                            {
                                writer.WriteBeginTag("span");
                                writer.WriteAttribute("style", "font-family: 'Times New Roman',Times,serif;");
                                writer.Write(HtmlTextWriter.TagRightChar);
                                writer.Write("Times New Roman");
                                writer.WriteEndTag("span");
                            });

                            items.AddValue("Trebuchet MS,Helvetica,sans-serif").Template(() =>
                            {
                                writer.WriteBeginTag("span");
                                writer.WriteAttribute("style", "font-family:'Trebuchet MS',Helvetica,sans-serif;");
                                writer.Write(HtmlTextWriter.TagRightChar);
                                writer.Write("Trebuchet MS");
                                writer.WriteEndTag("span");
                            });

                            items.AddValue("Verdana,Geneva,sans-serif").Template(() =>
                            {
                                writer.WriteBeginTag("span");
                                writer.WriteAttribute("style", "font-family: Verdana,Geneva,sans-serif;");
                                writer.Write(HtmlTextWriter.TagRightChar);
                                writer.Write("Verdana");
                                writer.WriteEndTag("span");
                            });
                        }
                    }).Options(opts => { opts.OnItemSelected = "$(\"#" + Component.Parent.Id + "\").richtextbox(\"runCmd\",\"fontName\",$(this).val())"; })
                    .Select("inherit");
                #endregion
            }, (id => { Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").combo(\"option\", \"selectedValue\", sender.getFontFarmily());"); }))
                //.Width(120)
            .AddCombo(combo =>
            {
                #region Add font size combo
                combo.Items(items =>
                  {
                      using (var writer = new HtmlTextWriter(this.ViewContext.Writer))
                      {
                          items.AddValue("inherit").Template(() =>
                          {
                              writer.WriteBeginTag("span");
                              writer.WriteAttribute("style", "font-size: inherit;");
                              writer.Write(HtmlTextWriter.TagRightChar);
                              writer.Write("(inherited size)");
                              writer.WriteEndTag("span");
                          });

                          items.AddValue("8pt").Template(() =>
                          {
                              writer.WriteBeginTag("span");
                              writer.WriteAttribute("style", "font-size: xx-small;");
                              writer.Write(HtmlTextWriter.TagRightChar);
                              writer.Write("1 (8pt)");
                              writer.WriteEndTag("span");
                          });
                          items.AddValue("10pt").Template(() =>
                          {
                              writer.WriteBeginTag("span");
                              writer.WriteAttribute("style", "font-size: x-small;");
                              writer.Write(HtmlTextWriter.TagRightChar);
                              writer.Write("2 (10pt)");
                              writer.WriteEndTag("span");
                          });
                          items.AddValue("12pt").Template(() =>
                          {
                              writer.WriteBeginTag("span");
                              writer.WriteAttribute("style", "font-size: small;");
                              writer.Write(HtmlTextWriter.TagRightChar);
                              writer.Write("3 (12pt)");
                              writer.WriteEndTag("span");
                          });
                          items.AddValue("14pt").Template(() =>
                          {
                              writer.WriteBeginTag("span");
                              writer.WriteAttribute("style", "font-size: medium;");
                              writer.Write(HtmlTextWriter.TagRightChar);
                              writer.Write("4 (14pt)");
                              writer.WriteEndTag("span");
                          });
                          items.AddValue("18pt").Template(() =>
                          {
                              writer.WriteBeginTag("span");
                              writer.WriteAttribute("style", "font-size: large;");
                              writer.Write(HtmlTextWriter.TagRightChar);
                              writer.Write("5 (18pt)");
                              writer.WriteEndTag("span");
                          });
                          items.AddValue("24pt").Template(() =>
                          {
                              writer.WriteBeginTag("span");
                              writer.WriteAttribute("style", "font-size: x-large;");
                              writer.Write(HtmlTextWriter.TagRightChar);
                              writer.Write("6 (24pt)");
                              writer.WriteEndTag("span");
                          });
                          items.AddValue("36pt").Template(() =>
                          {
                              writer.WriteBeginTag("span");
                              writer.WriteAttribute("style", "font-size: xx-large;");
                              writer.Write(HtmlTextWriter.TagRightChar);
                              writer.Write("7 (36pt)");
                              writer.WriteEndTag("span");
                          });
                      }
                  }).Options(opts => { opts.OnItemSelected = "$(\"#" + Component.Parent.Id + "\").richtextbox(\"runCmd\",\"fontSize\",$(this).val())"; })
                  .Select("inherit");
                #endregion
            }, (id => { Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").combo(\"option\", \"selectedValue\", sender.getFontSize());"); }))
                //.Width(100)
            .AddColorPicker("d-rte-icon d-rte-foreColor", "$(\"#" + Component.Parent.Id + "\").richtextbox(\"runCmd\",\"forecolor\",cmd);")
            .AddColorPicker("d-rte-icon d-rte-backColor", "$(\"#" + Component.Parent.Id + "\").richtextbox(\"runCmd\",\"hilitecolor\",cmd);")
            .AddSeparator()
            .AddIcon("d-rte-icon d-rte-bold", cmdScript("setBold"), null, "Bold (CTRL+B)", (id =>
            {
                Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isBold());");
            }), true, false)
            .AddIcon("d-rte-icon d-rte-italic", cmdScript("setItalic"), null, "Italic (CTRL+I)", (id =>
            {
                Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isItalic());");
            }), true, false)
            .AddIcon("d-rte-icon d-rte-underline", cmdScript("setUnderline"), null, "Underline (CTRL+U)", (id =>
            {
                Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isUnderline());");
            }), true, false)
            .AddIcon("d-rte-icon d-rte-strikeThrough", cmdScript("setStrikeThrough"), null, "Strikethrough", (id =>
            {
                Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isLineThrough());");
            }), true, false);
            return this;
        }

        /// <summary>
        /// Including 
        /// </summary>
        /// <returns></returns>
        public RichTextBoxPaneBuilder AddParagraphTools()
        {
            var factory = new RichTextBoxToolbarFactory(this.Component, this.ViewContext,this.ViewDataContainer);

            factory.Add()
            .AddPush("d-rte-icon d-rte-justifyLeft", cmdScript("setJustifyLeft"), "Align left", "Justify", states =>
                 {
                     states.Add()
                         .Icons("d-rte-icon d-rte-justifyLeft")
                         .Select(true)
                         .ToggleClass("d-rte-icon-button")
                         .SetValue(false);

                     states.Add()
                         .Icons("d-rte-icon d-rte-justifyLeft")
                         .ToggleClass("d-rte-icon-button-push")
                         .SetValue(true);
                 }, (id => { Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isJustifyLeft());"); }))

                 .AddPush("d-rte-icon d-rte-justifyCenter", cmdScript("setJustifyCenter"), "Align center", "Justify", states =>
                 {
                     states.Add()
                         .Icons("d-rte-icon d-rte-justifyCenter")
                         .Select(true)
                         .ToggleClass("d-rte-icon-button")
                         .SetValue(false);

                     states.Add()
                         .Icons("d-rte-icon d-rte-justifyCenter")
                         .ToggleClass("d-rte-icon-button-push")
                         .SetValue(true);
                 }, (id => { Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isJustifyCenter());"); }))
                 .AddPush("d-rte-icon d-rte-justifyRight", cmdScript("setJustifyRight"), "Align right", "Justify", states =>
                 {
                     states.Add()
                         .Icons("d-rte-icon d-rte-justifyRight")
                         .Select(true)
                         .ToggleClass("d-rte-icon-button")
                         .SetValue(false);

                     states.Add()
                         .Icons("d-rte-icon d-rte-justifyRight")
                         .ToggleClass("d-rte-icon-button-push")
                         .SetValue(true);
                 }, (id => { Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isJustifyRight());"); }))
                 .AddPush("d-rte-icon d-rte-justifyFull", cmdScript("setJustifyFull"), "Align full", "Justify", states =>
                 {
                     states.Add()
                         .Icons("d-rte-icon d-rte-justifyFull")
                         .Select(true)
                         .ToggleClass("d-rte-icon-button")
                         .SetValue(false);

                     states.Add()
                         .Icons("d-rte-icon d-rte-justifyFull")
                         .ToggleClass("d-rte-icon-button-push")
                         .SetValue(true);
                 }, (id => { Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isJustifyNone());"); }))
                 .AddSeparator()

                 .AddIcon("d-rte-icon d-rte-indent", cmdScript("setIndent"), "Indent")
                 .AddIcon("d-rte-icon d-rte-outdent", cmdScript("setOutdent"), "Outdent")

                 .AddSeparator()

                 .AddPush("d-rte-icon d-rte-insertOrderedList", cmdScript("insertOrderedList"), "Numbered list", "OrderingList", states =>
                 {
                     states.Add()
                         .Icons("d-rte-icon d-rte-justifyFull")
                         .Select(true)
                         .ToggleClass("d-rte-icon-button")
                         .SetValue(false);

                     states.Add()
                         .Icons("d-rte-icon d-rte-insertOrderedList")
                         .ToggleClass("d-rte-icon-button-push")
                         .SetValue(true);
                 }, (id => { Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isOrderList());"); }))

                 .AddPush("d-rte-icon d-rte-insertUnorderedList", cmdScript("insertUnorderedList"), "Bullet list", "OrderingList", states =>
                 {
                     states.Add()
                         .Icons("d-rte-icon d-rte-insertUnorderedList")
                         .Select(true)
                         .ToggleClass("d-rte-icon-button")
                         .SetValue(false);

                     states.Add()
                         .Icons("d-rte-icon d-rte-insertUnorderedList")
                         .ToggleClass("d-rte-icon-button-push")
                         .SetValue(true);
                 }, (id => { Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isUnorderList());"); }));

            return this;
        }

        private string cmdScript(string cmd)
        {
            return "$(\"#" + Component.Parent.Id + "\").richtextbox(\"" + cmd + "\");";
        }

        /// <summary>
        /// Including Format code block,Link,unlink
        /// </summary>
        /// <returns></returns>
        public RichTextBoxPaneBuilder AddFormatTools()
        {
            var factory = new RichTextBoxToolbarFactory(this.Component, this.ViewContext,this.ViewDataContainer);
            factory.Add()
                .AddIcon("d-rte-icon d-rte-superscript", cmdScript("setSuperscript"), null, "SuperScript", (id =>
            {
                Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isSup());");
            }), true)
                .AddIcon("d-rte-icon d-rte-subscript", cmdScript("setSubscript"), null, "SubScript", (id =>
            {
                Component.Parent.OnNormalized.AppendLine("$(\"#" + id + "\").buttonex(\"option\", \"value\", sender.isSub());");
            }), true)
                .AddIcon("d-rte-icon d-rte-insertHorizontalRule", cmdScript("insertHorizontalRule"), "Insert HorizontalRule")
                .AddIcon("d-rte-icon d-rte-insertParagraph", cmdScript("insertParagraph"), "InsertParagraph")
                .AddIcon("d-rte-icon d-rte-insertDate", cmdScript("insertDate"), "InsertDate")
                .AddIcon("d-rte-icon d-rte-insertTime", cmdScript("insertTime"), "InsertTime");
            //this.Component.Tools[]
            return this;
        }

        /// <summary>
        /// Including Copy,Cut,Paste
        /// </summary>
        /// <returns></returns>
        public RichTextBoxPaneBuilder AddClipboardTools()
        {
            var factory = new RichTextBoxToolbarFactory(this.Component, this.ViewContext,this.ViewDataContainer);
            factory.Add()
            .AddIcon("d-rte-icon d-rte-print", cmdScript("print"), "Print")
            .AddIcon("d-rte-icon d-rte-copy", cmdScript("copy"), "Copy")
            .AddIcon("d-rte-icon d-rte-cut", cmdScript("cut"), "Cut")
            .AddIcon("d-rte-icon d-rte-paste", cmdScript("paste"), "Paste");
            return this;
        }
    }




}